using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;

namespace sforceExplorer
{
	/// <summary>
	/// Summary description for DataGridHyperLinkColumn.
	/// </summary>
	public class DataGridHyperLinkColumn : 
		DataGridTextBoxColumn
	{
		int _offSet = 0;

		bool attachedToEvent = false;
		string _linkLabelText = string.Empty;
		string _label = string.Empty;

		public delegate void LinkLabelColumnClickDelegate(object sender, LinkLabelColumnEventArgs e);
		public event LinkLabelColumnClickDelegate LinkLabelColumnClick;
        		
		/// <summary>
		/// Creates a new instance of the ExtendedDataGridLinkLabelColumn class.
		/// </summary>
		public DataGridHyperLinkColumn():base()
		{
			MenuItem menu1 = new MenuItem("&Show in Browser");
			MenuItem menu2 = new MenuItem("&Copy ID");
			menu1.Click+=new EventHandler(menu1_Click);
			menu2.Click+=new EventHandler(menu2_Click);
			base.TextBox.ContextMenu = new ContextMenu(new MenuItem[] {menu1, menu2});
		}

		/// <summary>
		/// Gets or sets the caption of the label.If empty, the value of the underlying item will be showed.
		/// </summary>
		[DefaultValue("")]
		[Description("The caption of the label. If empty, the value of the underlying item will be showed.")]
		public string LinkLabelText
		{
			get
			{
				return _linkLabelText;
			}
			set
			{
				_linkLabelText = value;
			}
		}

		/// <summary>
		/// Gets or sets the top offset of the text.
		/// </summary>
		[System.ComponentModel.DefaultValue(0)]
		public int OffSet
		{
			get
			{
				return _offSet;
			}
			set
			{
				_offSet = value;
			}
		}

		protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
		{
			if(!attachedToEvent)
			{
				attachedToEvent = true;
				this.DataGridTableStyle.DataGrid.MouseMove +=new MouseEventHandler(DataGrid_MouseMove);
				this.DataGridTableStyle.DataGrid.MouseUp += new MouseEventHandler(DataGrid_MouseUp);
				this.TextBox.MouseUp +=new MouseEventHandler(DataGrid_MouseUp);
			}

			Font font = new Font(this.TextBox.Font.FontFamily, this.TextBox.Font.Size,FontStyle.Underline);
			Brush brush = new SolidBrush(Color.Blue);
			g.FillRectangle(backBrush, bounds);
			this._label = this.GetColumnValueAtRow(source, rowNum).ToString();
			ToolTip tt = ((frmMain)this.DataGridTableStyle.DataGrid.FindForm()).toolTip1;
			tt.SetToolTip(this.DataGridTableStyle.DataGrid, "Click to view salesforce.com details, " + System.Environment.NewLine + "Right click to copy Id value to clipboard.");
			if(this.LinkLabelText == string.Empty)
				g.DrawString(this.GetColumnValueAtRow(source, rowNum).ToString(), font, brush, bounds.X, bounds.Y + this.OffSet);
			else
				g.DrawString(this.LinkLabelText, font, brush, bounds.X, bounds.Y + this.OffSet);

		}

		protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
		{
			return;
		}

		private void DataGrid_MouseMove(object sender, MouseEventArgs e)
		{
			// X & Y are in the grid' coordinates. If they are in screen coordinates, call dataGrid1.PointToClient method 
			System.Drawing.Point pt = new Point(e.X, e.Y); 
 
			DataGrid.HitTestInfo hti = this.DataGridTableStyle.DataGrid.HitTest(pt); 

			ToolTip tt = ((frmMain)this.DataGridTableStyle.DataGrid.FindForm()).toolTip1;

			if(hti.Type == DataGrid.HitTestType.Cell) 
			{ 
				int rowNum = this.DataGridTableStyle.GridColumnStyles.IndexOf(this);
				if(rowNum == hti.Column)
				{
					tt.Active = true;
					this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Hand;
				}
				else
				{
					this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
					tt.Active = false;
				}
			} 
			else
			{
				this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
				tt.Active = false;
			}
		}

		private void DoLeftButtonClick(LinkLabelColumnEventArgs e) 
		{
			if(this.LinkLabelColumnClick != null)
				this.LinkLabelColumnClick(this, e);
			
		}

		private void DoRightButtonClick(LinkLabelColumnEventArgs e) 
		{
			this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
			this.TextBox.ContextMenu.Show(this.DataGridTableStyle.DataGrid, new Point(e.X, e.Y));
		}

		private void DataGrid_MouseUp(object sender, MouseEventArgs e)
		{
			// X & Y are in the grid' coordinates. If they are in screen coordinates, call dataGrid1.PointToClient method 
			System.Drawing.Point pt = new Point(e.X, e.Y); 
 
			DataGrid.HitTestInfo hti = this.DataGridTableStyle.DataGrid.HitTest(pt); 

			
			if(hti.Type == DataGrid.HitTestType.Cell) 
			{ 
				int rowNum = this.DataGridTableStyle.GridColumnStyles.IndexOf(this);
				if(rowNum == hti.Column)
				{
					BindingManagerBase bm = 
						this.DataGridTableStyle.DataGrid.BindingContext[this.DataGridTableStyle.DataGrid.DataSource, 
						this.DataGridTableStyle.DataGrid.DataMember]; 
							
					LinkLabelColumnEventArgs clickArgs = 
						new LinkLabelColumnEventArgs(bm.Current, this.MappingName, e.X, e.Y);

					this.TextBox.Tag = clickArgs;

					if (e.Button != MouseButtons.Right) 
					{
						this.DoLeftButtonClick(clickArgs);
//						if(this.LinkLabelColumnClick != null)
//							this.LinkLabelColumnClick(this, clickArgs);
					}
					else 
					{
						if (hti.Row == this.DataGridTableStyle.DataGrid.CurrentCell.RowNumber)
							this.DoRightButtonClick(clickArgs);
//						this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
//						this.TextBox.Tag = clickArgs;
//						this.TextBox.ContextMenu.Show(this.DataGridTableStyle.DataGrid, new Point(e.X, e.Y));
					}
				}
			}
		}

		private void menu1_Click(object sender, EventArgs e)
		{
			DoLeftButtonClick((LinkLabelColumnEventArgs)this.TextBox.Tag);
		}

		private void menu2_Click(object sender, EventArgs e)
		{
			Clipboard.SetDataObject(((LinkLabelColumnEventArgs)this.TextBox.Tag).Id);
		}
	}

	/// <summary>
	/// EventArgs used by the ExtendedDataGridLinkLabelColumn class.
	/// </summary>
	public class LinkLabelColumnEventArgs: EventArgs
	{
		object rowValue;
		string labelText;
		string id;
		int x;
		int y;
		/// <summary>
		/// Creates a new instance of the LinkLabelColumnEventArgs class.
		/// </summary>
		/// <param name="rowValue">The value of the underlying row.</param>
		public LinkLabelColumnEventArgs(object rowValue, string columnName, int X, int Y):base()
		{
			this.rowValue = rowValue;
			this.labelText = labelText;
			this.id = ((System.Data.DataRowView)rowValue).Row[columnName].ToString();
			this.x = X;
			this.y = Y;
		}

		public int X { get { return x; } set { x = value; } }
		public int Y { get { return y; } set { y = value; } }

		public string Id 
		{
			get 
			{
				return id;
			}
			set { id = value; }
		}
		public string LabelText 
		{
			get { return labelText; }
			set { labelText = value; }
		}
		/// <summary>
		/// Gets or sets the value of the underlying row.
		/// </summary>
		public object RowValue
		{
			get
			{
				return rowValue;
			}
			set
			{
				rowValue = value;
			}
		}
	}
}
